home *** CD-ROM | disk | FTP | other *** search
/ QRZ! Ham Radio 8 / QRZ Ham Radio Callsign Database - Volume 8.iso / pc / files / t_unix / j109lxa4.tar / pathname.c < prev    next >
C/C++ Source or Header  |  1994-06-04  |  4KB  |  148 lines

  1. /* Convert relative to absolute pathnames
  2.  * Copyright 1991 Phil Karn, KA9Q
  3.  */
  4. #include <stdio.h>
  5. #include "global.h"
  6. #include "dirutil.h"
  7. #include "config.h"
  8. #ifdef CALLSERVER
  9. #include <string.h>
  10. extern char *CDROM; /* buckbook.c: defines CDROM drive letter e.g. "s:"  */
  11. #endif
  12.  
  13. void crunch __ARGS((char *buf,char *path));
  14.  
  15. /* Given a working directory and an arbitrary pathname, resolve them into
  16.  * an absolute pathname. Memory is allocated for the result, which
  17.  * the caller must free
  18.  */
  19. char *
  20. pathname(cd,path)
  21. char *cd;       /* Current working directory */
  22. char *path;     /* Pathname argument */
  23. {
  24.     register char *buf;
  25. #ifdef  MSDOS
  26.     char *cp,c;
  27.     char *tbuf;
  28.     int tflag = 0;
  29. #endif
  30. #ifdef CALLSERVER
  31.   int drive = 0;  /* is there a drive spec to preserve? */
  32. #endif
  33.  
  34.     if(cd == NULLCHAR || path == NULLCHAR)
  35.         return NULLCHAR;
  36.  
  37. #ifdef  MSDOS
  38.     /* If path has any backslashes, make a local copy with them
  39.      * translated into forward slashes
  40.      */
  41.     if(strchr(path,'\\') != NULLCHAR){
  42.         tflag = 1;
  43.         cp = tbuf = mallocw(strlen(path) + 1);
  44.         while((c = *path++) != '\0'){
  45.             if(c == '\\')
  46.                 *cp++ = '/';
  47.             else
  48.                 *cp++ = c;
  49.         }
  50.         *cp = '\0';
  51.         path = tbuf;
  52.     }
  53. #endif
  54.  
  55.     /* Strip any leading white space on args */
  56.     while(*cd == ' ' || *cd == '\t')
  57.         cd++;
  58.     while(*path == ' ' || *path == '\t')
  59.         path++;
  60.  
  61. #ifdef CALLSERVER
  62.   if (CDROM != NULLCHAR && strncmp(path, CDROM, 2) == 0)  {
  63.     buf = strdup(path);
  64.     return buf;
  65.   }
  66.   if (CDROM != NULLCHAR &&  strncmp(cd, CDROM, 2) == 0) drive = 1;
  67.                                 /* make a note  */
  68. #endif
  69.     /* Allocate and initialize output buffer; user must free */
  70.     buf = mallocw((unsigned)strlen(cd) + strlen(path) + 10);        /* fudge factor */
  71.     buf[0] = '\0';
  72.  
  73.     /* Interpret path relative to cd only if it doesn't begin with "/" */
  74.     if(path[0] != '/')
  75.         crunch(buf,cd);
  76.  
  77. #ifdef CALLSERVER
  78.   else (drive = 0);
  79. #endif
  80.     crunch(buf,path);
  81.  
  82.     /* Special case: null final path means the root directory */
  83.     if(buf[0] == '\0'){
  84.         buf[0] = '/';
  85.         buf[1] = '\0';
  86.     }
  87. #ifdef  MSDOS
  88.     if(tflag)
  89.         free(tbuf);
  90. #endif
  91. #ifdef CALLSERVER
  92.   if (drive)  {
  93.     cp = buf;
  94.     while (*cp != '\0') *cp = *(cp++ + 1);
  95.   }
  96. #endif
  97.     return buf;
  98. }
  99.  
  100. /* Process a path name string, starting with and adding to
  101.  * the existing buffer
  102.  */
  103. void
  104. crunch(buf,path)
  105. char *buf;
  106. register char *path;
  107. {
  108.     register char *cp;
  109.     
  110.  
  111.     cp = buf + strlen(buf); /* Start write at end of current buffer */
  112.     
  113.     /* Now start crunching the pathname argument */
  114.     for(;;){
  115.         /* Strip leading /'s; one will be written later */
  116.         while(*path == '/')
  117.             path++;
  118.         if(*path == '\0')
  119.             break;          /* no more, all done */
  120.         /* Look for parent directory references, either at the end
  121.          * of the path or imbedded in it
  122.          */
  123.         if(strcmp(path,"..") == 0 || strncmp(path,"../",3) == 0){
  124.             /* Hop up a level */
  125.             if((cp = strrchr(buf,'/')) == NULLCHAR)
  126.                 cp = buf;       /* Don't back up beyond root */
  127.             *cp = '\0';             /* In case there's another .. */
  128.             path += 2;              /* Skip ".." */
  129.             while(*path == '/')     /* Skip one or more slashes */
  130.                 path++;
  131.         /* Look for current directory references, either at the end
  132.          * of the path or imbedded in it
  133.          */
  134.         } else if(strcmp(path,".") == 0 || strncmp(path,"./",2) == 0){
  135.             /* "no op" */
  136.             path++;                 /* Skip "." */
  137.             while(*path == '/')     /* Skip one or more slashes */
  138.                 path++;
  139.         } else {
  140.             /* Ordinary name, copy up to next '/' or end of path */
  141.             *cp++ = '/';
  142.             while(*path != '/' && *path != '\0')
  143.                 *cp++ = *path++;
  144.         }
  145.     }
  146.     *cp++ = '\0';
  147. }
  148.